﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace AutoLoginAndRun
{
    public class RegistryHelper
    {
        private RegistryHelper() { }

        private static Properties.Settings opts = Properties.Settings.Default;

        public static void GetAutoLoginAccess(out bool canWrite)
        {
            const string KeyName = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";
            canWrite = CanWriteRegistry(KeyName);
        }
        public static void GetAutoLogin(out bool canWrite)
        {
            const string KeyName = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";

            opts.AutoLogin = false;
            opts.AutoLoginUser = null;
            opts.AutoLoginPwd = null;

            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(KeyName, false))
                {
                    object value;

                    value = key.GetValue("AutoAdminLogon");
                    opts.AutoLogin = value != null && value.ToString() == "1";

                    value = key.GetValue("DefaultUserName", Environment.UserName);
                    if (value != null)
                        opts.AutoLoginUser = value.ToString();
                    value = key.GetValue("DefaultPassword");
                    if (value != null)
                        opts.AutoLoginPwd = value.ToString();
                }
                canWrite = CanWriteRegistry(KeyName);
            }
            catch
            {
                opts.AutoLogin = false;
                canWrite = false;
            }
        }

        public static void GetAutoStart(out bool canWrite)
        {
            opts.AutoStart = false;
            opts.AutoStartPath = null;

            const string KeyName = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";

            try
            {
                using (RegistryKey key = Registry.CurrentUser.OpenSubKey(KeyName, false))
                {
                    object value = key.GetValue("AutoLoginAndRun");

                    if (value != null && value.ToString() != "")
                    {
                        opts.AutoStartPath = value.ToString().Trim('\"');
                        opts.AutoStart = true;
                    }
                    else
                    {
                        opts.AutoStart = false;
                    }
                }
                canWrite = CanWriteRegistry(KeyName);
            }
            catch
            {
                opts.AutoStart = false;
                canWrite = false;
            }
        }

        public static bool SetAutoLogin()
        {
            const string KeyName = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";

            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(KeyName, true))
                {
                    if (opts.AutoLogin)
                    {
                        key.SetValue("DefaultUserName", opts.AutoLoginUser, RegistryValueKind.String);
                        key.SetValue("DefaultPassword", opts.AutoLoginPwd, RegistryValueKind.String);
                        key.SetValue("AutoAdminLogon", "1", RegistryValueKind.String);
                    }
                    else
                    {
                        foreach (string valueName in key.GetValueNames())
                        {
                            //if (valueName == "DefaultUserName")
                            //    key.DeleteValue("DefaultUserName");
                            if (valueName == "DefaultPassword")
                                key.DeleteValue("DefaultPassword");
                            if (valueName == "AutoAdminLogon")
                                key.SetValue("AutoAdminLogon", "0");
                        }
                    }
                    return true;
                }
            }
            catch (System.Security.SecurityException)
            {
                return false;
            }
            catch (System.UnauthorizedAccessException)
            {
                return false;
            }
            catch
            {
                return false;
            }
        }

        public static bool SetAutoStart()
        {
            const string KeyName = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";

            try
            {
                using (RegistryKey key = Registry.CurrentUser.OpenSubKey(KeyName, true))
                {
                    if (opts.AutoStart && System.IO.File.Exists(opts.AutoStartPath))
                    {
                        key.SetValue("AutoLoginAndRun", "\"" + opts.AutoStartPath + "\"", RegistryValueKind.String);
                    }
                    else
                    {
                        foreach (string valueName in key.GetValueNames())
                        {
                            if (valueName == "AutoLoginAndRun")
                            {
                                key.DeleteValue("AutoLoginAndRun");
                                break;
                            }
                        }
                    }
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        private static bool CanWriteRegistry(string KeyName)
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(KeyName, true))
                {
                    key.SetValue("Test", "");
                    key.DeleteValue("Test");
                    return true;
                }
            }
            catch (System.Security.SecurityException)
            {
                return false;
            }
            catch (System.UnauthorizedAccessException)
            {
                return false;
            }
            catch
            {
                return false;
            }
        }
    }
}
